Mockito is a popular open-sourced Java mocking framework which is used for testing. The idea of mocking is widespread out in many other languages because it is indeed useful and essential for creating unit tests.
You may be unfamiliar with the term, mock
. A mock
is like creating a disguised thing that behaves like the real thing which can execute given instructions. The Mockito is a tool to do just that. A mock
would not actually create any real object so it just creates a type of a thing you are mocking.
For example (using the famous list example):
Let’s take a look at the example of what I mean by creating a type. testIntsMock
is a mock object of a List:
@Test
public void testListMock()
{
testIntsMock.add(30);
testIntsMock.add(20);
testIntsMock.add(10);
verify(testIntsMock).add(10);
assertEquals(0, testIntsMock.size());
}
Note the mocked list (testIntsMock) did not actually add any values but we’ve successfully verified that the add operation is called which ensures us that functionally it is doing what it supposed to do.
Let’s say that we wanted actual behavior changes with the mocked item. The Mockito supports this as well. We can use Spy instead of plain Mock to do our mocking:
@Test
public void testListSpy()
{
testIntsSpy.add(30);
testIntsSpy.add(20);
testIntsSpy.add(10);
verify(testIntsSpy).add(10);
when(testIntsSpy.get(1)).thenReturn(50);
assertEquals(3, testIntsSpy.size());
assertTrue(30 == testIntsSpy.get(0));
assertTrue(50 == testIntsSpy.get(1));
}
Note the Spy
list is now has the actual size 3 instead of 0 from our Mock
example. So why use Spy
? Well, the example above revealed already a couple of powerful mocking ability the Spy
can do instead of using a real object. You can manipulate the spied object using when/doAnswer etc. Also, you can make verify
calls to ensure the function you are testing is working.
Examples are available and found easily online. It is redundant to duplicate their work here. I would encourage you to look for examples or examples are found in various tests in src/test of my Java algorithm playground
I find the following Mockito functionalities most useful at least from my experiences. It is definitely worth mentioning here.
when(extractor.extract(eq(in))).thenAnswer(new Answer<String>() {
@Override
public String answer(InvocationOnMock invocation) throws Throwable {
InputStream in = Util.getInputStream(filename, Parser.class);
return new String(IOUtils.toByteArray(in));
}
});
Or you can also have when
at the end using doAnswer
:
doAnswer(new Answer<ReturnValueObject>() {
@Override
public ReturnValueObject answer(final InvocationOnMock invocation) throws Throwable {
final Integer originalAmount = (invocation.getArguments())[0];
final Integer chargedAmount = (invocation.getArguments())[1];
final ReturnValueObject returnedValue = new ReturnValueObject();
returnedValue.setCost(new Cost(originalAmount - chargedAmount));
return returnedValue;
}
}).when(priceChangeRequestService).quickCharge(any(Integer.class), any(Integer.class));
ServiceClassA firstMock = mock(ServiceClassA.class);
ServiceClassB secondMock = mock(ServiceClassB.class);
Mockito.doNothing().when(firstMock).methodOne();
Mockito.doNothing().when(secondMock).methodTwo();
//create inOrder object passing any mocks that need to be verified in order
InOrder inOrder = inOrder(firstMock, secondMock);
inOrder.verify(firstMock).methodOne();
inOrder.verify(secondMock).methodTwo();
This will make sure that firstMock’s methodOne is called before secondMock’s methodTwo is invoked.
ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
verify(mock).doSomething(argument.capture());
assertEquals("John", argument.getValue().getName());
Above will capture the object, Person, which would let you use it to assertValues are what you expected at the end.
This is very useful as there are times where you would like the Mockito to capture the value as they are being verified which later you will be able to assert.